package fun.ticsmyc.rpc.nacos.loadbalance.impl;

import com.alibaba.nacos.api.naming.pojo.Instance;
import fun.ticsmyc.rpc.nacos.loadbalance.LoadBalancer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Ticsmyc
 * @date 2020-10-30 11:47
 */
public class RoundRobinNacosLoadBalancer implements LoadBalancer {

    private static final Logger logger= LoggerFactory.getLogger(RoundRobinNacosLoadBalancer.class);

    private static AtomicInteger index;

    private volatile static RoundRobinNacosLoadBalancer INSTANCE;
    private RoundRobinNacosLoadBalancer(){}
    public static RoundRobinNacosLoadBalancer getInstance(){
        if(INSTANCE == null){
            synchronized (RoundRobinNacosLoadBalancer.class){
                if(INSTANCE == null){
                    INSTANCE = new RoundRobinNacosLoadBalancer();
                    index = new AtomicInteger(0);
                }
            }
        }
        return INSTANCE;
    }

    @Override
    public Instance select(List<Instance> instances) {
        int serverCount = instances.size();
        int retryTime =0;

        //有几个服务提供者就重试几次
        while(retryTime++ <serverCount){
            int i = incrementAndGetModulo(serverCount);
            Instance instance = instances.get(i);
            if(instance.isEnabled() && instance.isHealthy()){
                logger.info("使用{}号服务",i);
                return instance;
            }
        }
        logger.error("没有可用服务");
        return null;

    }

    private int incrementAndGetModulo(int modulo){
        for(;;){
            int current = index.get();
            int next =(current+1)%modulo;
            if( index.compareAndSet(current,next)){
                return next;
            }
        }
    }
}
